package com.design.pattern.behavior.template.jdbc.framework;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class JdbcTemplate<T> {
    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public final List<T> executeQuery(String sql, RowMapper<T> rowMapper, Object[] values){
        //1.获取连接
        try ( Connection connection = this.getConnection();
              //2.创建语句集
              PreparedStatement ps = this.createPrepareStatement(connection, sql);

              //3.执行语句
              ResultSet rs = this.executeQuery(ps, values);){

            //4.处理结果集
            List<T> result = this.pareseResultSet(rs, rowMapper);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.关闭结果集
            //7.关闭语句集
            //8.关闭连接
        }
        return null;
    }

    private List<T> pareseResultSet(ResultSet rs, RowMapper<T> rowMapper) throws Exception {
        List<T> result = new ArrayList<>();
        int rowNum = 1;
        while(rs.next()) {
            result.add(rowMapper.mapRow(rs, rowNum + 1));
        }
        return result;
    }

    private ResultSet executeQuery(PreparedStatement ps, Object[] values) throws SQLException {
        for (int i = 0; i < values.length; i++){
            ps.setObject(i, values[i]);
        }
        return ps.executeQuery();
    }

    protected PreparedStatement createPrepareStatement(Connection connection, String sql) throws SQLException {
        return connection.prepareStatement(sql);
    }

    protected  Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}
